package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.annotation.DistributedLock;
import com.sc.nft.dao.DaoSchoolArticleDao;
import com.sc.nft.dao.UserCreatorInfoDao;
import com.sc.nft.entity.DaoSchoolArticle;
import com.sc.nft.entity.DaoSchoolArticleChild;
import com.sc.nft.entity.DaoSchoolChild;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.util.AudioUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 文章表(DaoSchoolArticle)表服务实现类
 *
 * @author makejava
 * @since 2023-03-13 16:20:43
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DaoSchoolArticleServiceImpl implements DaoSchoolArticleService {

    private final DaoSchoolArticleDao daoSchoolArticleDao;

    private final DaoSchoolChildService daoSchoolChildService;

    private final DaoSchoolTopService daoSchoolTopService;

    private final DaoSchoolArticleChildService daoSchoolArticleChildService;

    private final DaoSchoolArticleMaterialService daoSchoolArticleMaterialService;

    private final UserCreatorInfoDao userCreatorInfoDao;

    @Override
    public Page<DaoSchoolArticlePageAdminVO> pageAdmin(PageRequest pageRequest) {
        return daoSchoolArticleDao.pageAdmin(pageRequest);
    }

    @Override
    @DistributedLock("DaoSchoolArticleService::deleteById")
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(Long id) {
        // 删除文章的同时,需要同时处理所有的引用该文章的子集,子集删除后.删除多少个子集,要处理多少个父集. 比如子集删除了3条,那么父级就要文章总数-3.用以这里来保证数据的同步性.
        // 获取子集文章数据.几个子集,对应的子集的文章总数-1,通过子集在去减去父集文章总数  并且删除掉子集文章中间表.文章素材关联表也要随之删除

        // 判定文章是否存在
        DaoSchoolArticle daoSchoolArticle = daoSchoolArticleDao.selectById(id);
        if (BeanUtil.isEmpty(daoSchoolArticle)) {
            throw new GlobalRunTimeException("数据不存在或已删除");
        }

        // 获取子集和文章关联表所有数据
        List<DaoSchoolArticleChild> daoSchoolArticleChildren = daoSchoolArticleChildService.selectByArticleId(id);
        // 循环删除匹配的子集and父级的文章数-1 删除对应的素材
        daoSchoolArticleChildren.forEach(daoSchoolArticleChild -> {
            // 子集-1
            daoSchoolChildService.totalSubOne(daoSchoolArticleChild.getSchoolChildId());
            // 子集数据
            DaoSchoolChild daoSchoolChild = daoSchoolChildService.selectById(daoSchoolArticleChild.getSchoolChildId());
            // 父集-1
            daoSchoolTopService.totalSubOne(daoSchoolChild.getSecondTopId());
            // 删除素材(不确定有没有素材,走一遍流程)
            daoSchoolArticleMaterialService.deleteByArticleId(id);
            // 删除文章.
            daoSchoolArticleChild.deleteById();
        });
        daoSchoolArticle.deleteById();
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveAdmin(DaoSchoolArticleSaveAdminDTO daoSchoolArticleSaveAdminDTO) {
        DaoSchoolArticle daoSchoolArticle = new DaoSchoolArticle();
        BeanUtil.copyProperties(daoSchoolArticleSaveAdminDTO, daoSchoolArticle);
        daoSchoolArticle.setDaoId(6L);
        daoSchoolArticle.setAudioType(AudioUtil.decision(daoSchoolArticleSaveAdminDTO.getAudio()));
        if (!StrUtil.isEmpty(daoSchoolArticle.getVideosUrl())) {
            if (StrUtil.isEmpty(daoSchoolArticle.getVideosImg())) {
                throw new GlobalRunTimeException("上传音频文件必须选择音频封面");
            }
        }
        daoSchoolArticle.insert();
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(DaoSchoolArticleUpdateByIdAdminDTO daoSchoolArticleUpdateByIdAdminDTO) {
        DaoSchoolArticle daoSchoolArticle = daoSchoolArticleDao.selectById(daoSchoolArticleUpdateByIdAdminDTO.getId());
        if (BeanUtil.isEmpty(daoSchoolArticle)) {
            throw new GlobalRunTimeException("数据不存在或已被删除");
        }

        DaoSchoolArticleUpdateByIdAdminDTO info = new DaoSchoolArticleUpdateByIdAdminDTO();
        BeanUtil.copyProperties(daoSchoolArticleUpdateByIdAdminDTO, info);
        daoSchoolArticleUpdateByIdAdminDTO.setId(null);
        if (BeanUtil.isEmpty(daoSchoolArticleUpdateByIdAdminDTO)) {
            throw new GlobalRunTimeException("参数不可以为空");
        }
        DaoSchoolArticle daoSchoolArticleInfo = new DaoSchoolArticle();
        BeanUtil.copyProperties(info, daoSchoolArticleInfo);
        // 前端有可能同时出现audio和audioType字段同时出现.所以这里需要判断一下
        if (!StrUtil.isEmpty(info.getAudio())) {
            daoSchoolArticleInfo.setAudioType(AudioUtil.decision(info.getAudio()));
        }
        daoSchoolArticleInfo.setDaoId(6L);
        if (!StrUtil.isEmpty(daoSchoolArticle.getVideosUrl())) {
            if (StrUtil.isEmpty(daoSchoolArticle.getVideosImg())) {
                throw new GlobalRunTimeException("上传音频文件必须选择音频封面");
            }
        }
        daoSchoolArticleInfo.updateById();
        return Boolean.TRUE;
    }

    /**
     * 获取没有被某个子集选中的文章
     *
     * @param daoSchoolArticleNotChildIdPageListDTO
     * @return
     */
    @Override
    public Page<DaoSchoolArticlePageAdminVO> selectByNotChildIdPageList(DaoSchoolArticleNotChildIdPageListDTO daoSchoolArticleNotChildIdPageListDTO) {
        return daoSchoolArticleDao.selectByNotChildIdPageList(daoSchoolArticleNotChildIdPageListDTO);
    }

    /**
     * 获取没有被置顶的文章
     *
     * @param daoSchoolArticleNotChildIdPageListDTO
     * @return
     */
    @Override
    public Page<DaoSchoolArticlePageAdminVO> selectByNotTopArticle(DaoSchoolArticleNotChildIdPageListDTO daoSchoolArticleNotChildIdPageListDTO) {
        return daoSchoolArticleDao.selectByNotTopArticle(daoSchoolArticleNotChildIdPageListDTO);
    }

    /**
     * 获取首页推荐文章
     *
     * @param daoSchoolArticleNotChildIdPageListDTO
     * @return
     */
    @Override
    public Page<DaoSchoolArticlePageAdminVO> homePageAdmin(DaoSchoolArticleNotChildIdPageListDTO daoSchoolArticleNotChildIdPageListDTO) {
        return daoSchoolArticleDao.homePageAdmin(daoSchoolArticleNotChildIdPageListDTO);
    }

    /**
     * 文章置顶
     *
     * @param list
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean articleTop(List<DaoSchoolArticleTopDTO> list) {
        if (list.size() > 9) {
            throw new GlobalRunTimeException("最大置顶上限为9条");
        }
        Integer articleTopIsExist = daoSchoolArticleDao.articleTopIsExist(list.stream().map(DaoSchoolArticleTopDTO::getId).collect(Collectors.toList()));
        if (articleTopIsExist > 0) {
            throw new GlobalRunTimeException("置顶文章条目已存在");
        }
        // 获取当前的置顶文章数据数量
        Integer articleTopCount = daoSchoolArticleDao.articleTopCount();
        if (9 - articleTopCount < list.size()) {
            throw new GlobalRunTimeException(StrUtil.format("当前最多可以新增{}条", 9 - articleTopCount));
        }
        daoSchoolArticleDao.articleTop(list);
        return Boolean.TRUE;
    }

    @Override
    public Boolean cancelArticleTop(List<DaoSchoolCancelArticleTopDTO> list) {
        daoSchoolArticleDao.cancelArticleTop(list);
        return Boolean.TRUE;
    }

    @Override
    public List<DaoSchoolTopHomeArticleListVO> getHomeTopArticle() {

        return daoSchoolArticleDao.getHomeTopArticle();
    }

    /**
     * 通过id获取文章
     *
     * @param articleId
     * @return
     */
    @Override
    public ArticleDetailsVO byIdGetArticle(Long articleId) {
        ArticleDetailsVO articleDetailsVO = daoSchoolArticleDao.byIdGetArticle(articleId);
        if (BeanUtil.isEmpty(articleDetailsVO)) {
            throw new GlobalRunTimeException("数据不存在或已被删除");
        }
        // 获取用户数据的挂在附件,不在乎附件是否为空
        List<ArticleMaterialVO> articleMaterial = daoSchoolArticleMaterialService.selectByArticleId(articleId);
        articleDetailsVO.setArticleMaterial(articleMaterial);

        // 新增文章观看人数
        increaseArticleViewsBasedOnId(articleId, 1);
        // 获取官方dao的头像和名字
        GetDaoByIdVO certainlyShowDao = userCreatorInfoDao.getCertainlyShowDao();
        articleDetailsVO.setNickName(certainlyShowDao.getNickName());
        articleDetailsVO.setCreatorAvatarImg(certainlyShowDao.getCreatorAvatarImg());
        return articleDetailsVO;
    }

    /**
     * 通过id增加文章浏览量
     *
     * @param id
     * @param browse
     * @return
     */
    @Override
    public Boolean increaseArticleViewsBasedOnId(Long id, Integer browse) {
        return daoSchoolArticleDao.increaseArticleViewsBasedOnId(id, browse);
    }

}
